import json
from django.core.paginator import Paginator
from django.db import transaction
from goods.models import SKU
from meiduo_mall.utils.response_code import RETCODE
from django import http
from django.shortcuts import render
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django_redis import get_redis_connection
from datetime import datetime
from orders.models import OrderInfo, OrderGoods
from users.models import Address, User


class OrderSettlementView(LoginRequiredMixin, View):
    def get(self, request):
        '''
        :param request:
        :return: 展示数据
        '''
        # 地址 　北京市 海淀区 东北旺西路8号中关村软件园 （李思 收） 182****7528
        user = request.user
        user_addresses = Address.objects.filter(pk=user.id)
        user_default_address = User.objects.get(pk=user.id)
        user_default_address_id = user_default_address.default_address_id

        # 图片　名称　数量　价格　小计
        # cart_dict[sku_id] = {
        #         'count': count,
        #         'selected': selected
        #     }
        redis_cli = get_redis_connection('carts')
        cart_dict = redis_cli.hgetall('carts%d' % user.id)
        cart_dict = {int(sku_id): int(count) for sku_id, count in cart_dict.items()}

        selected_list = redis_cli.smembers('selected%d' % user.id)
        selected_list = [int(sku_id) for sku_id in selected_list]
        skus = SKU.objects.filter(pk__in=selected_list, is_launched=True)

        order_list = []
        total_count = 0
        freight = 10
        for sku in skus:
            order_list.append({
                'default_image': sku.default_image.url,
                'name': sku.name,
                'count': cart_dict[sku.id],
                'price': sku.price,
                'total_amount': sku.price * cart_dict[sku.id]
            })
            total_count += sku.price * cart_dict[sku.id]
        context = {
            'order_list': order_list,
            'user_addresses': user_addresses,
            'default_address_id': user_default_address_id,
            'total_count': total_count,
            'total_pay': total_count + freight,
            'freight': freight
        }
        return render(request, 'place_order.html', context)


class OrderCommitView(View):
    '''订单提交'''

    def post(self, request):
        param_dict = json.loads(request.body.decode())
        address_id = param_dict.get('address_id')
        pay_method = param_dict.get('pay_method')
        user = request.user
        # 验证
        if not all([address_id, pay_method]):
            return http.JsonResponse({'code': RETCODE, 'errmsg': '参数不全'})
        try:
            Address.objects.get(pk=address_id)
        except:
            return http.JsonResponse({'code': RETCODE, 'errmsg': '收货地址有误'})
        if pay_method not in [1, 2]:
            return http.JsonResponse({'code': RETCODE, 'errmsg': '支付方式有误'})
        # 从购物车中查询选中的商品
        redis_cli = get_redis_connection('carts')
        cart_dict = redis_cli.hgetall('carts%d' % user.id)
        cart_dict = {int(sku_id): int(count) for sku_id, count in cart_dict.items()}
        selected_list = redis_cli.smembers('selected%d' % user.id)
        selected_list = [int(sku_id) for sku_id in selected_list]
        skus = SKU.objects.filter(pk__in=selected_list, is_launched=True)
        # 创建订单对象 使用事务
        with transaction.atomic():
            sid = transaction.savepoint()
            # 年月日十分秒
            now = datetime.now()
            order_id = '%s%09d' % (now.strftime("%Y%m%d%H%M%S"), user.id)
            total_count = 0
            total_amount = 0
            if pay_method == 1:
                status = 2
            else:
                status = 1
            order = OrderInfo.objects.create(
                order_id=order_id,
                user_id=user.id,
                address_id=address_id,
                total_count=total_count,
                total_amount=total_amount,
                freight=10,
                pay_method=pay_method,
                status=status,
            )

            # 判断库存
            # 修改库存销量
            for sku in skus:
                count = cart_dict[sku.id]
                if sku.stock < cart_dict[sku.id]:
                    transaction.savepoint_rollback(sid)
                    return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '库存不足'})

                # sku.stock -= count
                # sku.sales += count
                # sku.save()
                stock_new = sku.stock - cart_dict[sku.id]
                sales_new = sku.stock - cart_dict[sku.id]
                SKU.objects.filter(pk=sku.id, stock=sku.stock).update(stock=stock_new, sales=sales_new)

                total_amount += sku.price * count
                total_count += count
                # 创建订单商品对象
                OrderGoods.objects.create(
                    order_id=order_id,
                    sku_id=sku.id,
                    count=count,
                    price=sku.price,
                )
            order.total_amount = total_amount
            order.total_count = total_count
            order.save()
            # 提交数据库
            transaction.savepoint_commit(sid)
            # 删除购物车数据
        redis_cli.hdel('carts%d' % user.id, *selected_list)
        redis_cli.delete('selected%d' % user.id)
        # 处理
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'order_id': order_id})


class OrderSuccessView(View):
    def get(self, request):
        order_id = request.GET.get('order_id')
        payment_amount = request.GET.get('payment_amount')
        pay_method = request.GET.get('pay_method')
        context = {
            'order_id': order_id,
            'payment_amount': payment_amount,
            'pay_method': pay_method
        }

        return render(request, 'order_success.html', context)


class OrderListView(View):
    def get(self, request, page_num):


        # 所有的订单号，总价，状态
        user = request.user
        orderinfoes = user.orderinfo_set.all().order_by('-create_time')
        # 分页
        paginator = Paginator(orderinfoes, 2)
        # 当前页的数据
        orderinfos = paginator.page(page_num)
        order_list = []
        for orderinfo in orderinfos:
            order_goods_list = []
            order_list.append({
                'order_id':orderinfo.order_id,
                'total_amount':orderinfo.total_amount,
                'skus':order_goods_list,
                'status':orderinfo.status
            })
            # 每一个订单的所有商品
            order_goods = orderinfo.skus.all()


            for order_good in order_goods:
                order_goods_list.append({
                    'name':order_good.sku.name,
                    'default_image':order_good.sku.default_image.url,
                    'price':order_good.price,
                    'count':order_good.count,
                    'total':order_good.price*order_good.count
                })
        context = {
            'order_list': order_list,
            'page_num': page_num,
            'page_total': paginator.num_pages
        }
        return render(request, 'user_center_order.html', context=context)


class OrderCommentView(View):
    def get(self, request):
        # 接收
        order_id = request.GET.get('order_id')
        # 验证
        try:
            order = OrderInfo.objects.get(pk=order_id)
        except:
            return render(request, '404.html')
        # 处理：查询订单中的商品
        skus = order.skus.filter(is_commented=False)
        sku_list = []
        for detail in skus:
            sku_list.append({
                'order_id': order_id,
                'sku_id': detail.sku.id,
                'default_image_url': detail.sku.default_image.url,
                'name': detail.sku.name,
                'price': str(detail.price)
            })
        # 响应
        context = {'skus': sku_list}
        return render(request, 'goods_judge.html', context)

    def post(self, request):
        param_dict = json.loads(request.body.decode())
        order_id = param_dict.get('order_id')
        sku_id = param_dict.get('sku_id')
        comment = param_dict.get('comment')
        score = param_dict.get('score')
        is_anonymous = param_dict.get('is_anonymous', False)

        # 验证
        if not all([order_id, sku_id, comment, score]):
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': '参数不完整'
            })
        # 订单商品是否存在
        try:
            order_goods = OrderGoods.objects.get(order_id=order_id, sku_id=sku_id)
        except:
            return http.JsonResponse({
                'code': RETCODE.PARAMERR,
                'errmsg': '不存在此订单商品对象'
            })

        # 处理
        # 1.保存订单商品的评论信息
        order_goods.comment = comment
        order_goods.score = score
        order_goods.is_anonymous = is_anonymous
        order_goods.is_commented = True
        order_goods.save()
        # 2.修改订单的状态
        # 一个订单可以包含多个商品，所有商品都评论后，则修改订单状态
        order = order_goods.order
        if order.skus.filter(is_commented=False).count() <= 0:
            order.status = 5
            order.save()

        # 响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': ''})


class OrderCommentlistView(View):
    def post(self, request, sku_id):
        order_goods = OrderGoods.objects.filter(sku_id=sku_id).order_id('-create_time')
        order_goods_list = []
        user = request.user
        for order_good in order_goods:
            order_goods_list.append({
                "username": user.name,
                "comment": order_good.comment,
                "score": order_good.score
            })

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'comment_list': order_goods_list})

